package com.ricchieri.util;

import java.io.Serializable;
import java.sql.Time;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

public class DateUtil implements Serializable {
	
	private static final long serialVersionUID = -3392364610495441334L;

	private static final long ONE_HOUR = 60 * 60 * 1000L;

	public static boolean isDateBetweenDates(Date dateToValidate, Date startDate, Date endDate) {
		Calendar startCalendar = Calendar.getInstance();
		startCalendar.setTime(startDate);
		
		Calendar endCalendar = Calendar.getInstance();
		endCalendar.setTime(endDate);
		
		Calendar calendarToValidate = Calendar.getInstance();
		calendarToValidate.setTime(dateToValidate);
		
		return !(calendarToValidate.before(startCalendar) || calendarToValidate.after(endCalendar));
	}
	
	public static int daysBetween(Date d1, Date d2){
		return (int)( (d2.getTime() - d1.getTime() ) / (ONE_HOUR * 24));
	}   	

	public static Date getDateWithOffset(Date date, int offset) {
		Calendar calTime = new GregorianCalendar();
		calTime.setTime(date);
		calTime.add(Calendar.DATE, offset);
		return calTime.getTime();
	}

	public static Date addDays(Date date, int daysAmount) {
		
		Calendar calendar = Calendar.getInstance();
		
		calendar.setTime(date);
		calendar.add(Calendar.DATE, daysAmount);
		
		return calendar.getTime();
	}

	public static boolean validTime(Integer startHour, Integer startMinute, Integer startAmPm,
			Integer endHour, Integer endMinute, Integer endAmPm){
		boolean result = true;
		
		Time startTime = Time.valueOf(startHour.toString().concat(":").concat(startMinute.toString()).concat(":00"));
		Time finishTime = Time.valueOf(endHour.toString().concat(":").concat(endMinute.toString()).concat(":00"));
		if ((startTime.after(finishTime) && startAmPm.intValue() == endAmPm.intValue())
				|| startAmPm.intValue() > endAmPm.intValue()) {
			result = false; 
		}
		
		return result;
	}
	
	public static boolean timeBeforeTime(Integer hour1, Integer minute1, Integer amPm1,
									Integer hour2, Integer minute2, Integer amPm2){
		
		Time time1 = Time.valueOf(hour1.toString().concat(":").concat(minute1.toString()).concat(":00"));
		Time time2 = Time.valueOf(hour2.toString().concat(":").concat(minute2.toString()).concat(":00"));
		if (amPm1.intValue() < amPm2.intValue() || 
			(amPm1.intValue() == amPm2.intValue() && time1.before(time2))) {
			return true;
		}
		
		return false;
	}

	public static boolean timeAfterTime(Integer hour1, Integer minute1, Integer amPm1,
									Integer hour2, Integer minute2, Integer amPm2){
		
		Time time1 = Time.valueOf(hour1.toString().concat(":").concat(minute1.toString()).concat(":00"));
		Time time2 = Time.valueOf(hour2.toString().concat(":").concat(minute2.toString()).concat(":00"));
		if (amPm1.intValue() > amPm2.intValue() || (amPm2.intValue() == amPm1.intValue()
				&& time1.after(time2))) {
			return true;
		}
		
		return false;
	}
	
	public static Date setTimeFromDate(Date date, Date time) {
		Calendar calTime = new GregorianCalendar();
		calTime.setTime(date);
		
		Calendar timeCalendar = Calendar.getInstance();
		timeCalendar.setTime(time);
		
		calTime.set(Calendar.HOUR_OF_DAY, timeCalendar.get(Calendar.HOUR_OF_DAY));
		calTime.set(Calendar.MINUTE, timeCalendar.get(Calendar.MINUTE));
		return calTime.getTime();
	}
	
	public static Time convertToTime(Date date) {
		return new java.sql.Time(date.getTime());
	}
	
	public static Date converToDate(Date date, Time time) {
		Calendar calDate = new GregorianCalendar();
		calDate.setTime(date);

		Calendar calTime = new GregorianCalendar();
		calTime.setTime(time);
     
		calDate.set(Calendar.HOUR_OF_DAY, calTime.get(Calendar.HOUR_OF_DAY));
		calDate.set(Calendar.MINUTE, calTime.get(Calendar.MINUTE));
		calDate.set(Calendar.SECOND, calTime.get(Calendar.SECOND));
		calDate.set(Calendar.MILLISECOND, calTime.get(Calendar.MILLISECOND));
	
        return calDate.getTime();
        
	}
	
	
	public static String formatDate(Date date) {
		SimpleDateFormat formatDateTime = new SimpleDateFormat("dd/MM/yyyy");

		return formatDateTime.format(date);
	}
	
	public static String formatTime(Time date) {
		SimpleDateFormat formatDateTime = new SimpleDateFormat("kk:mm:ss");

		return formatDateTime.format(date);
	}
	
	public static String formatDateTime(Date date) {
		SimpleDateFormat formatDateTime = new SimpleDateFormat("dd/MM/yyyy kk:mm");

		return formatDateTime.format(date);
	}
	
	public static Date changeToEndDay(Date date) {
		
		Calendar calDate = new GregorianCalendar();
		calDate.setTime(date);
     
		calDate.set(Calendar.HOUR_OF_DAY, 23);
		calDate.set(Calendar.MINUTE, 59);
		calDate.set(Calendar.SECOND, 59);
		calDate.set(Calendar.MILLISECOND, 59);
	
        return calDate.getTime();
		
	}
	
	public static Date changeToStartDay(Date date) {
		Calendar calDate = new GregorianCalendar();
		calDate.setTime(date);
     
		calDate.set(Calendar.HOUR_OF_DAY, 0);
		calDate.set(Calendar.MINUTE, 0);
		calDate.set(Calendar.SECOND, 0);
		calDate.set(Calendar.MILLISECOND, 0);
	
        return calDate.getTime();
	}
	
	public static int obtaintDayOfWeek(Date date) {
		Calendar calDate = new GregorianCalendar();
		calDate.setTime(date);
		return calDate.get(Calendar.DAY_OF_WEEK);
	}
	
	public static int obtainDayOfWeekWithAdd(Date date, int daysAmount){
		return obtaintDayOfWeek(addDays(date, daysAmount));
	}
}
